﻿using System;
using System.Collections;
using System.Data;
using System.IO;
using System.Text.RegularExpressions;

namespace mlnx_os_sysdump_analyzer
{
	/// <summary>
	/// Description of PortInfo.
	/// </summary>
	public class PortInfo
	{
		
		DataTable ethPortsDT = null;
		DataTable ibPortsDT = null;
        DataTable spinePortDT = null;
        
		private bool KEEP_RUNNING;
        private string OUTPUT_DIR_PATH;
        private bool timeouts = false;
        
		public PortInfo(ref bool KEEP_RUNNING, ref string OUTPUT_DIR_PATH)
        {
            this.KEEP_RUNNING = KEEP_RUNNING;   
            this.OUTPUT_DIR_PATH = OUTPUT_DIR_PATH;
           //
           // init ib ports table
           //
           // create a DataTable
            ibPortsDT = new DataTable();
            // add columns
            ibPortsDT.Columns.Add("Slot#", typeof(int));
            ibPortsDT.Columns.Add("Port#", typeof(int));
            ibPortsDT.Columns.Add("Slot Type", typeof(string));
            ibPortsDT.Columns.Add("Logical port state", typeof(string));
            ibPortsDT.Columns.Add("Physical port state", typeof(string));
            ibPortsDT.Columns.Add("Current line rate", typeof(string));
            ibPortsDT.Columns.Add("Supported speeds", typeof(string));
            ibPortsDT.Columns.Add("Speed", typeof(string));
            ibPortsDT.Columns.Add("Supported widths", typeof(string));
            ibPortsDT.Columns.Add("Width", typeof(string));
            ibPortsDT.Columns.Add("Max supported MTUs", typeof(string));
            ibPortsDT.Columns.Add("MTU", typeof(string));
            ibPortsDT.Columns.Add("Cable identifier", typeof(string));
            ibPortsDT.Columns.Add("Cable/module type", typeof(string));
            ibPortsDT.Columns.Add("Cable infiniband speeds", typeof(string));
            ibPortsDT.Columns.Add("Cable vendor", typeof(string));
            ibPortsDT.Columns.Add("Cable cable length", typeof(string));
            ibPortsDT.Columns.Add("Cable revision", typeof(string));
            ibPortsDT.Columns.Add("Cable part number", typeof(string));
            ibPortsDT.Columns.Add("Cable serial number", typeof(string));
            //rx
            ibPortsDT.Columns.Add("RX bytes", typeof(long));
            ibPortsDT.Columns.Add("RX packets", typeof(long));
            ibPortsDT.Columns.Add("RX errors", typeof(long));
            ibPortsDT.Columns.Add("Symbol errors", typeof(long));
            ibPortsDT.Columns.Add("VL15 dropped packets", typeof(long));
            //tx
            ibPortsDT.Columns.Add("TX bytes", typeof(long));
            ibPortsDT.Columns.Add("TX packets", typeof(long));
            ibPortsDT.Columns.Add("TX wait", typeof(long));
            ibPortsDT.Columns.Add("TX discarded packets", typeof(long));
           
            // -----------------------------
           
            //
            // init eth ports table
            //
            // create a DataTable
            ethPortsDT = new DataTable();
            // add columns
            ethPortsDT.Columns.Add("Port#", typeof(double));
            ethPortsDT.Columns.Add("Admin state", typeof(string));
            ethPortsDT.Columns.Add("Operational state", typeof(string));
            ethPortsDT.Columns.Add("Description", typeof(string));
            ethPortsDT.Columns.Add("Mac address", typeof(string));
            ethPortsDT.Columns.Add("MTU", typeof(string));
            ethPortsDT.Columns.Add("Flow-control", typeof(string));
            ethPortsDT.Columns.Add("Actual speed", typeof(string));
            ethPortsDT.Columns.Add("Switchport mode", typeof(string));
            ethPortsDT.Columns.Add("Cable identifier", typeof(string));
            ethPortsDT.Columns.Add("Cable/module type", typeof(string));
            ethPortsDT.Columns.Add("Cable ethernet speed and type", typeof(string));
            ethPortsDT.Columns.Add("Cable vendor", typeof(string));
            ethPortsDT.Columns.Add("Cable cable length", typeof(string));
            ethPortsDT.Columns.Add("Cable revision", typeof(string));
            ethPortsDT.Columns.Add("Cable part number", typeof(string));
            ethPortsDT.Columns.Add("Cable serial number", typeof(string));
            // rx
            ethPortsDT.Columns.Add("RX frames", typeof(long));
            ethPortsDT.Columns.Add("RX unicast frames", typeof(long));
            ethPortsDT.Columns.Add("RX multicast frames", typeof(long));
            ethPortsDT.Columns.Add("RX broadcast frames", typeof(long));
            ethPortsDT.Columns.Add("RX octets", typeof(long));
            ethPortsDT.Columns.Add("RX error frames", typeof(long));
            ethPortsDT.Columns.Add("RX discard frames", typeof(long));
            
            // tx
            ethPortsDT.Columns.Add("TX frames", typeof(long));
            ethPortsDT.Columns.Add("TX unicast frames", typeof(long));
            ethPortsDT.Columns.Add("TX multicast frames", typeof(long));
            ethPortsDT.Columns.Add("TX broadcast frames", typeof(long));
            ethPortsDT.Columns.Add("TX octets", typeof(long));
            ethPortsDT.Columns.Add("TX discard frames", typeof(long));
           
            // -----------------------------
            //
            // init spine ports table
            //
            // create a DataTable
            spinePortDT = new DataTable();
            // add columns
            spinePortDT.Columns.Add("Slot#", typeof(int));
            spinePortDT.Columns.Add("Port#", typeof(int));
            spinePortDT.Columns.Add("Slot Type", typeof(string));
            spinePortDT.Columns.Add("Connected to slot", typeof(string));
            spinePortDT.Columns.Add("Connected to port", typeof(int));
            spinePortDT.Columns.Add("Connected device active", typeof(int));
            spinePortDT.Columns.Add("Error state", typeof(int));
            spinePortDT.Columns.Add("Logical port state", typeof(string));
            spinePortDT.Columns.Add("Physical port state", typeof(string));
            spinePortDT.Columns.Add("Current line rate", typeof(string));
            spinePortDT.Columns.Add("Supported speeds", typeof(string));
            spinePortDT.Columns.Add("Speed", typeof(string));
            spinePortDT.Columns.Add("Supported widths", typeof(string));
            spinePortDT.Columns.Add("Width", typeof(string));
            spinePortDT.Columns.Add("Max supported MTUs", typeof(string));
            spinePortDT.Columns.Add("MTU", typeof(string));
            spinePortDT.Columns.Add("VL capabilities", typeof(string));
            spinePortDT.Columns.Add("Operational VLs", typeof(string));
            spinePortDT.Columns.Add("Description", typeof(string));


            // -----------------------------

		} // end PortInfo constructor
		//
        //----------------------------------------------------

        public DataTable getSpinePortsTable()
        {
            return spinePortDT;
        } // end getIBPortsTable
        //
        //----------------------------------------------------

		public DataTable getIBPortsTable()
		{
			return ibPortsDT;
		} // end getIBPortsTable
		//
        //----------------------------------------------------
		
		public DataTable getETHPortsTable()
		{
			return ethPortsDT;
		} // end getETHPortsTable
		//
        //----------------------------------------------------

        private void addPortToSpineDT(SpinePortInfoIBFields pi)
        {
            if (spinePortDT == null || pi == null)
            {
                return;
            }
            spinePortDT.Rows.Add(pi.slotNum,
                pi.portNum,
                pi.slotType,
                pi.connectedToSlot,
                pi.connectedToPort,
                pi.connectedDeviceActive,
                pi.errorState,
                pi.logicalPortState,
                pi.physicalPortState,
                pi.currentLineRate,
                pi.supportedSpeeds,
                pi.speed,
                pi.supportedWidths,
                pi.width,
                pi.maxSupportedMTUs,
                pi.MTU,
                pi.VLCapabilities,
                pi.operationalVLs,
                pi.description);
        }
        //
        //----------------------------------------------------

        private void addPortToIBDT(PortInfoIBFields pi)
        {
        	if (ibPortsDT == null || pi == null)
        	{
        		return;
        	}
            ibPortsDT.Rows.Add(pi.slotNum,
                pi.portNum,
                pi.slotType,
                pi.logicalPortState,
                pi.physicalPortState,
                pi.currentLineRate,
                pi.supportedSpeeds,
                pi.speed,
                pi.supportedWidths,
                pi.width,
                pi.maxSupportedMTUs,
                pi.MTU,
                pi.identifier,
                pi.cableModuleType,
                pi.infinibandSpeeds,
                pi.vendor,
                pi.cableLength,
                pi.revision,
                pi.partNumber,
                pi.serialNumber,
                pi.RXBytes,
                pi.RXPackets,
                pi.RXErrors,
                pi.symbolErrors,
                pi.VL15DroppedPackets,
                pi.TXBytes,
                pi.TXPackets,
                pi.TXWait,
                pi.TXDiscardedPackets);
        }
        //
        //----------------------------------------------------
        
        private void addPortToETHDT(PortInfoETHFields pi)
        {
        	if (ibPortsDT == null || pi == null)
        	{
        		return;
        	}
            ethPortsDT.Rows.Add(pi.portNum, 
                pi.adminState, 
                pi.operationalState,
                pi.description,
                pi.MacAddress,
                pi.MTU,
                pi.FlowControl,
                pi.actualSpeed,
                pi.switchPortMode,
                pi.identifier,
                pi.cableModuleType,
                pi.ethernetSpeedAndType,
                pi.vendor,
                pi.cableLength,
                pi.revision,
                pi.partNumber,
                pi.serialNumber,
                pi.RXFrames,
                pi.RXUnicastFrames,
                pi.RXMulticastFrames,
                pi.RXBroadcastFrames,
                pi.RXOctets,
                pi.RXErrorFrames,
                pi.RXDiscardFrames,
                pi.TXFrames,
                pi.TXUnicastFrames,
                pi.TXMulticastFrames,
                pi.TXBroadcastFrames,
                pi.TXOctets,
                pi.TXDiscardFrames);
        }
        //
        //----------------------------------------------------
        
        public void scanPortInfo(object param)
        {
        	string srcFilePath = (string)param;
            if (srcFilePath == null)
                return;
            int lastIbPort = 0, lastIbSlot = 0;
            StreamReader sr = new StreamReader(srcFilePath);
            bool scannedIbPorts = false;

            try
            {
            	// go to the port info section
                while (KEEP_RUNNING && sr.Peek() >= 0)
                {
                    if (sr.ReadLine().Contains("port info"))
                    {
                        break;
                    }
                }
                string slotType = "";
                while (KEEP_RUNNING && sr.Peek() >= 0)
                {
                    // read line
                    string line = sr.ReadLine();
                    if (line.Contains("timed out after"))
                    {
                        timeouts = true;
                    }
                    try
                    {
                        //
                    	// SX IB
                    	//
                        if (line.Contains("Slot")) 
                        {
                            string tmp = Regex.Split(line, " ")[1];
                            slotType = "1U";
                            // line/spine ?
                            if (tmp.Contains("L"))
                            {
                                tmp = Regex.Replace(tmp, "L", "");
                                slotType = "Leaf";
                            }
                            if (tmp.Contains("S"))
                            {
                                tmp = Regex.Replace(tmp, "S", "");
                                slotType = "Spine";
                            }
                            
                            int slotNum = Int32.Parse(tmp);
                            int portNum = Int32.Parse(Regex.Split(line, " ")[3]);

                            if (slotType.Equals("Spine"))
                            {
                                if (spinePortDT.Rows.Count < (36 * (slotNum - 1)) + portNum) 
                                {
                                    SpinePortInfoIBFields spineTmpPort = new SpinePortInfoIBFields();
                                    // set slot and port numbers
                                    spineTmpPort.slotNum = slotNum;
                                    spineTmpPort.portNum = portNum;
                                    spineTmpPort.slotType = slotType;
                                    scanIBSpinePortInfo(ref sr, spineTmpPort); // get all the info about this port
                                }
                            }
                            else // leaf or 1U
                            {
                                if (!scannedIbPorts && (lastIbSlot < slotNum || lastIbPort < portNum))
                                {
                                    PortInfoIBFields tmpPortIB = new PortInfoIBFields();
                                    // set slot and port numbers
                                    tmpPortIB.slotNum = slotNum;
                                    tmpPortIB.portNum = portNum;
                                    tmpPortIB.slotType = slotType;
                                    scanIBPortInfo(ref sr, tmpPortIB);
                                }
                                else
                                {
                                    scannedIbPorts = true;
                                	scanIBPortCableInfo(ref sr, slotNum, portNum);
                                }
                                lastIbPort = portNum;	lastIbSlot = slotNum;
                            }
                        } 
                        //
	            		// end of SX IB
	            		// --------------------------------------------
	            		//
                        else
                        { 
                        	//
                    		// SX Eth
                    		//
                    		if ((line.Contains("Eth1/") || line.Contains("Port 1/")) && !line.Contains("Negotiation"))
                        	{
	                            PortInfoETHFields tmpPortEth = new PortInfoETHFields();
	                            tmpPortEth.portNum = 0;
	                            string []tmp = Regex.Split(line, "/");
	                            if (tmp.Length == 2)
	                            {
	                            	if (tmp[1].Contains(" "))
	                                {
	                                	tmp[1] = Regex.Split(tmp[1], " ")[0];
	                                }
	                                tmpPortEth.portNum = Int32.Parse(tmp[1]);
	                            }
	                            if (tmp.Length == 3)
	                            {
	                                tmpPortEth.portNum = Int32.Parse(tmp[1]);
	                                if (tmp[2].Contains(" "))
	                                {
	                                	tmp[2] = Regex.Split(tmp[2], " ")[0];
	                                }
	                                tmpPortEth.portNum = tmpPortEth.portNum + ((double)Int32.Parse(tmp[2]))/10;
	                            }
	                            
	                            if (line.Contains("Port"))
                        		{
	                            	// scan cable info
                        			scanETHPortCableInfo(ref sr, tmpPortEth.portNum);
                        		}
	                            else
	                            {
	                            	//scan port info
	                            	scanETHPortInfo(ref sr, tmpPortEth);
	                            }
                        	}
                            //
                    		// end of SX Eth
                    		// --------------------------------------------
                    		//
                        	else
                        	{
	                            //
	                        	// FabricIT
	                        	//
	                            if (line.Contains("Module"))
	                            {
	                                int slotNum = 0, portNum = 0;
	                                string tmp = Regex.Split(line, " ")[1];
	                                slotType = "1U";
	                                // line/spine ?
	                                if (tmp.Contains("L"))
	                                {
	                                    slotType = "Leaf";
	                                    tmp = Regex.Replace(tmp, "L", "");
	                                    slotNum = Int32.Parse(tmp);
	                                    portNum = Int32.Parse(Regex.Split(line, " ")[3]);
	                                }
	                                else if (tmp.Contains("IS"))
	                                {
	                                    slotType = "1U";
	                                    slotNum = 1;
	                                    portNum = Int32.Parse(Regex.Split(line, " ")[3]);
	                                }
	                                else if (tmp.Contains("S"))
	                                {
	                                    slotType = "Spine";
	                                    tmp = Regex.Replace(tmp, "S", "");
	                                    slotNum = Int32.Parse(tmp);
	                                    portNum = Int32.Parse(Regex.Split(line, " ")[4]);
	                                }
	
	                                if (slotType.Equals("Spine"))
	                                {
                                        if (spinePortDT.Rows.Count < (36 * (slotNum - 1)) + portNum)
	                                    {
	                                        SpinePortInfoIBFields spineTmpPort = new SpinePortInfoIBFields();
	                                        // set slot and port numbers
	                                        spineTmpPort.slotNum = slotNum;
	                                        spineTmpPort.portNum = portNum;
	                                        spineTmpPort.slotType = slotType;
	                                    	scanIBSpinePortInfo(ref sr, spineTmpPort); // get all the info about this port
	                                    }
	                                }
	                                else
	                                { // leaf or 1U
                                        if (!scannedIbPorts && (lastIbSlot < slotNum || lastIbPort < portNum))
                                        {
                                            PortInfoIBFields tmpPortIB = new PortInfoIBFields();
                                            // set slot and port numbers
                                            tmpPortIB.slotNum = slotNum;
                                            tmpPortIB.portNum = portNum;
                                            tmpPortIB.slotType = slotType;
                                            scanIBPortInfo(ref sr, tmpPortIB);
                                        }
                                        else
                                        {
                                            scannedIbPorts = true;
                                            scanIBPortCableInfo(ref sr, slotNum, portNum);
                                        }
                                        lastIbPort = portNum; lastIbSlot = slotNum;
	                                }
	                            }
	                            //
	                    		// end of FIT
	                    		// --------------------------------------------
	                    		//
                        	}
                        }

                    }//try
                    catch 
                    {  }
                    if (line.Contains("licenses info") || line.Contains("Negotiation"))
                    {
                        sr.Dispose();
                        return;
                    }
                }// end while
            }//try
            catch { }
            sr.Dispose();
        }
        //
        //----------------------------------------------------
        
        private void scanIBSpinePortInfo(ref StreamReader sr, SpinePortInfoIBFields spineTmpPort)
        {
        	while (KEEP_RUNNING && sr.Peek() >= 0)
            {
                // read line
                string line = sr.ReadLine();
                if (line.Contains("timed out after"))
                {
                    timeouts = true;
                }
                try
                {
                    if (line.Contains("Connected to") && !line.Contains("port"))
		            {
		                spineTmpPort.connectedToSlot = Regex.Split(line, ":")[1];
		            }
		            if (line.Contains("Connected to port"))
		            {
                        string tmp = Regex.Split(line, ":")[1];
                        if (tmp.Contains(" -"))
                        {
                            spineTmpPort.connectedToPort = -1; // not connected
                        }
                        else
                        {
                            spineTmpPort.connectedToPort = Int32.Parse(tmp);
                        }
		            }
		            if (line.Contains("Connected device active"))
		            {
                        string tmp = Regex.Split(line, ":")[1];
                        if (tmp.Contains(" -"))
                        {
                            spineTmpPort.connectedDeviceActive = -1; // not connected
                        }
                        else
                        {
                            spineTmpPort.connectedDeviceActive = Int32.Parse(tmp);
                        }
		            }
		            // Leaf is active
		            if (line.Contains("Leaf is active"))
		            {
                        string tmp = Regex.Split(line, ":")[1];
                        if (tmp.Contains(" -"))
                        {
                            spineTmpPort.connectedDeviceActive = -1;
                        }
                        else
                        {
                            spineTmpPort.connectedDeviceActive = Int32.Parse(tmp);
                        }
		            }
		            if (line.Contains("Error state "))
		            {
                        string tmp = Regex.Split(line, ":")[1];
                        if (tmp.Contains(" -"))
                        {
                            spineTmpPort.errorState = -1;
                        }
                        else
                        {
                            spineTmpPort.errorState = Int32.Parse(tmp);
                        }
		            }
		            if (line.Contains("Logical port state"))
		            {
		                spineTmpPort.logicalPortState = Regex.Split(line, ":")[1];
		            }
		            if (line.Contains("Physical port state"))
		            {
		                spineTmpPort.physicalPortState = Regex.Split(line, ":")[1];
		            }
		            if (line.Contains("Current line rate"))
		            {
		                spineTmpPort.currentLineRate = Regex.Split(line, ":")[1];
		            }
		            if (line.Contains("Supported speeds"))
		            {
		                spineTmpPort.supportedSpeeds = Regex.Split(line, ":")[1];
		            }
		            if (line.Contains("Speed"))
		            {
		                spineTmpPort.speed = Regex.Split(line, ":")[1];
		            }
		            if (line.Contains("Supported widths"))
		            {
		                spineTmpPort.supportedWidths = Regex.Split(line, ":")[1];
		            }
		            if (line.Contains("Width"))
		            {
		                spineTmpPort.width = Regex.Split(line, ":")[1];
		            }
		            if (line.Contains("Max supported MTUs"))
		            {
		                spineTmpPort.maxSupportedMTUs = Regex.Split(line, ":")[1];
		            }
		            if (line.Contains("MTU"))
		            {
		                spineTmpPort.MTU = Regex.Split(line, ":")[1];
		            }
		            if (line.Contains("VL capabilities"))
		            {
		                spineTmpPort.VLCapabilities = Regex.Split(line, ":")[1];
		            }
		            if (line.Contains("Operational VLs"))
		            {
		                spineTmpPort.operationalVLs = Regex.Split(line, ":")[1];
		                break;
		            }
                }
                catch {}
        	} // end while
            try
            {
                string line1 = sr.ReadLine();
                if (line1.Contains("Description"))
                {
                    spineTmpPort.description = Regex.Split(line1, ":")[1];
                }
            }
            catch { }

            addPortToSpineDT(spineTmpPort);
        }
        //
        //----------------------------------------------------
        
        private void scanIBPortInfo(ref StreamReader sr,  PortInfoIBFields tmpPort)
        {
        	while (KEEP_RUNNING && sr.Peek() >= 0)
            {
                // read line
                string line = sr.ReadLine();
                if (line.Contains("timed out after"))
                {
                    timeouts = true;
                }
                if (line.Contains("Negotiation"))
                {
                	break;
                }
                try
                {
					if (line.Contains("Logical port state"))
                    {
                        tmpPort.logicalPortState = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("Physical port state"))
                    {
                        tmpPort.physicalPortState = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("Current line rate"))
                    {
                        tmpPort.currentLineRate = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("Supported speeds"))
                    {
                        tmpPort.supportedSpeeds = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("Speed"))
                    {
                        tmpPort.speed = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("Supported widths"))
                    {
                        tmpPort.supportedWidths = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("Width"))
                    {
                        tmpPort.width = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("Max supported MTUs"))
                    {
                        tmpPort.maxSupportedMTUs = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("MTU"))
                    {
                        tmpPort.MTU = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("VL capabilities"))
                    {
                        tmpPort.VLCapabilities = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("Operational VLs"))
                    {
                        tmpPort.operationalVLs = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("Description"))
                    {
                        tmpPort.description = Regex.Split(line, ":")[1];
                    }
                    //
                    if (line.Contains("RX bytes"))
                    {
                        string tmp = Regex.Split(line, ":")[1];
                        if (tmp.Contains(" -"))
                        {
                            tmpPort.RXBytes = 0;
                        }
                        else
                        {
                             tmpPort.RXBytes = long.Parse(tmp);
                        }
                    }
                    if (line.Contains("RX packets"))
                    {
                        string tmp = Regex.Split(line, ":")[1];
                        if (tmp.Contains(" -"))
                        {
                            tmpPort.RXPackets = 0;
                        }
                        else
                        {
                            tmpPort.RXPackets = long.Parse(tmp);
                        }
                    }
                    if (line.Contains("RX errors"))
                    {
                        string tmp = Regex.Split(line, ":")[1];
                        if (tmp.Contains(" -"))
                        {
                            tmpPort.RXErrors = 0;
                        }
                        else
                        {
                            tmpPort.RXErrors = long.Parse(tmp);
                        }
                    }
                    if (line.Contains("Symbol errors"))
                    {
                        string tmp = Regex.Split(line, ":")[1];
                        if (tmp.Contains(" -"))
                        {
                            tmpPort.symbolErrors = 0;
                        }
                        else
                        {
                            tmpPort.symbolErrors = long.Parse(tmp);
                        }
                    }
                    if (line.Contains("VL15 dropped packets"))
                    {
                        string tmp = Regex.Split(line, ":")[1];
                        if (tmp.Contains(" -"))
                        {
                            tmpPort.VL15DroppedPackets = 0;
                        }
                        else
                        {
                            tmpPort.VL15DroppedPackets = long.Parse(tmp);
                        }
                    }
                    //
                    if (line.Contains("TX bytes"))
                    {
                        string tmp = Regex.Split(line, ":")[1];
                        if (tmp.Contains(" -"))
                        {
                            tmpPort.TXBytes = 0;
                        }
                        else
                        {
                            tmpPort.TXBytes = long.Parse(tmp);
                        }
                    }
                    if (line.Contains("TX packets"))
                    {
                        string tmp = Regex.Split(line, ":")[1];
                        if (tmp.Contains(" -"))
                        {
                            tmpPort.TXPackets = 0;
                        }
                        else
                        {
                            tmpPort.TXPackets = long.Parse(tmp);
                        }
                    }
                    if (line.Contains("TX wait"))
                    {
                        string tmp = Regex.Split(line, ":")[1];
                        if (tmp.Contains(" -"))
                        {
                            tmpPort.TXWait = 0;
                        }
                        else
                        {
                            tmpPort.TXWait = long.Parse(tmp);
                        }
                        break;
                    }
                }
                catch{}
        	}
            try
            {
                string line1 = sr.ReadLine();
                if (line1.Contains("TX discarded packets"))
                {
                    string tmp = Regex.Split(line1, ":")[1];
                    if (tmp.Contains(" -"))
                    {
                        tmpPort.TXDiscardedPackets = 0;
                    }
                    else
                    {
                        tmpPort.TXDiscardedPackets = long.Parse(tmp);
                    }
                }
            }
            catch { }
		    addPortToIBDT(tmpPort);
        }
        //
        //----------------------------------------------------
        
        private void scanIBPortCableInfo(ref StreamReader sr, int slotNum, int portNum)
        {
        	int index = 1;
        	for (int i = 0 ; i < ibPortsDT.Rows.Count ; i++)
        	{
        		if (ibPortsDT.Rows[i]["Port#"].Equals(portNum) && ibPortsDT.Rows[i]["Slot#"].Equals(slotNum))
        		{
        			index = i; 
        			break;
        		}
        	}
        	
        	while (KEEP_RUNNING && sr.Peek() >= 0)
            {
                // read line
                string line = sr.ReadLine();
                if (line.Contains("timed out after"))
                {
                    timeouts = true;
                }
                try
                {
                    if (line.Contains("identifier"))
                    {
                       ibPortsDT.Rows[index]["Cable identifier"] = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("cable/ module type"))
                    {
                        ibPortsDT.Rows[index]["Cable/module type"] = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("infiniband speeds"))
                    {
                        ibPortsDT.Rows[index]["Cable infiniband speeds"] = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("vendor"))
                    {
                        ibPortsDT.Rows[index]["Cable vendor"] = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("cable length"))
                    {
                        ibPortsDT.Rows[index]["Cable cable length"] = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("part number"))
                    {
                        ibPortsDT.Rows[index]["Cable part number"] = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("revision"))
                    {
                        ibPortsDT.Rows[index]["Cable revision"] = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("serial number"))
                    {
                        ibPortsDT.Rows[index]["Cable serial number"] = Regex.Split(line, ":")[1];
                        return;
                    }
                }
                catch {}
        	}
        }
        //
        //----------------------------------------------------
        
        private void scanETHPortInfo(ref StreamReader sr, PortInfoETHFields tmpPort)
        { 
        	while (KEEP_RUNNING && sr.Peek() >= 0)
            {
                // read line
                string line = sr.ReadLine();
                if (line.Contains("timed out after"))
                {
                    timeouts = true;
                }
                try
                {
        			if (line.Contains("Admin state"))
                        {
                            tmpPort.adminState = Regex.Split(line, ":")[1];
                        }
                        if (line.Contains("Operational state"))
                        {
                            tmpPort.operationalState = Regex.Split(line, ":")[1];
                        }
                        if (line.Contains("Description"))
                        {
                            tmpPort.description = Regex.Split(line, ":")[1];
                        }
                        if (line.Contains("Mac address"))
                        {
                            tmpPort.MacAddress = Regex.Split(line, "address:")[1];
                        }
                        if (line.Contains("MTU"))
                        {
                            tmpPort.MTU = Regex.Split(line, ":")[1];
                        }
                        if (line.Contains("Flow-control"))
                        {
                            tmpPort.FlowControl = Regex.Split(line, ":")[1];
                        }
                        if (line.Contains("Actual speed"))
                        {
                            tmpPort.actualSpeed = Regex.Split(line, ":")[1];
                        }
                        if (line.Contains("Switchport mode"))
                        {
                            tmpPort.switchPortMode = Regex.Split(line, ":")[1];
                        }
                        //
                        if (line.Contains("Rx"))
                        {
                            while (KEEP_RUNNING && sr.Peek() >= 0)
                            {
                                // read line
                                line = sr.ReadLine();
                                if (line.Contains("frames") || line.Contains("packets"))
                                {
                                    tmpPort.RXFrames = long.Parse(Regex.Split(line, "  ")[1]);
                                }
                                if (line.Contains("unicast"))
                                {
                                    tmpPort.RXUnicastFrames = long.Parse(Regex.Split(line, "  ")[1]);
                                }
                                if (line.Contains("multicast"))
                                {
                                    tmpPort.RXMulticastFrames = long.Parse(Regex.Split(line, "  ")[1]);
                                }
                                if (line.Contains("broadcast"))
                                {
                                    tmpPort.RXBroadcastFrames = long.Parse(Regex.Split(line, "  ")[1]);
                                }
                                if (line.Contains("octets") || line.Contains("bytes"))
                                {
                                    tmpPort.RXOctets = long.Parse(Regex.Split(line, "  ")[1]);
                                }
                                if (line.Contains("error"))
                                {
                                    tmpPort.RXErrorFrames = long.Parse(Regex.Split(line, "  ")[1]);
                                }
                                if (line.Contains("discard"))
                                {
                                    tmpPort.RXDiscardFrames = long.Parse(Regex.Split(line, "  ")[1]);
                                    break;
                                }
                            }
                        }
                        //
                        if (line.Contains("Tx"))
                        {
                            while (KEEP_RUNNING && sr.Peek() >= 0)
                            {
                                // read line
                                line = sr.ReadLine();
                                if (line.Contains("frames") || line.Contains("packets"))
                                {
                                    tmpPort.TXFrames = long.Parse(Regex.Split(line, "  ")[1]);
                                }

                                if (line.Contains("unicast"))
                                {
                                    tmpPort.TXUnicastFrames = long.Parse(Regex.Split(line, "  ")[1]);
                                }
                                if (line.Contains("multicast"))
                                {
                                    tmpPort.TXMulticastFrames = long.Parse(Regex.Split(line, "  ")[1]);
                                }
                                if (line.Contains("broadcast"))
                                {
                                    tmpPort.TXBroadcastFrames = long.Parse(Regex.Split(line, "  ")[1]);
                                }
                                if (line.Contains("octets") || line.Contains("bytes"))
                                {
                                    tmpPort.TXOctets = long.Parse(Regex.Split(line, "  ")[1]);
                                }
                                if (line.Contains("error"))
                                {
                                    tmpPort.TXErrorFrames = long.Parse(Regex.Split(line, "  ")[1]);
                                }
                                if (line.Contains("discard"))
                                {
                                    tmpPort.TXDiscardFrames = long.Parse(Regex.Split(line, "  ")[1]);
                                    addPortToETHDT(tmpPort);
                                    return;
                                }
                            }
                        }
                }
                catch {}
        	}
        }
        //
        //----------------------------------------------------
        
        private void scanETHPortCableInfo(ref StreamReader sr, double dPortNum)
        { 
        	// connected cable info
        	int index = 1;
        	for (int i = 0 ; i < ethPortsDT.Rows.Count ; i++)
        	{
        		if (ethPortsDT.Rows[i]["Port#"].Equals(dPortNum))
        		{
        			index = i; 
        			break;
        		}
        	} 
        	
        	while (KEEP_RUNNING && sr.Peek() >= 0)
            {
                // read line
                string line = sr.ReadLine();
                if (line.Contains("timed out after"))
                {
                    timeouts = true;
                }
                try
                {
                    if (line.Contains("identifier"))
                    {
                        ethPortsDT.Rows[index]["Cable identifier"] = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("cable/ module type"))
                    {
                        ethPortsDT.Rows[index]["Cable/module type"] =  Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("ethernet speed and type"))
                    {
                        ethPortsDT.Rows[index]["Cable ethernet speed and type"] =  Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("vendor"))
                    {
                        ethPortsDT.Rows[index]["Cable vendor"] = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("cable_length"))
                    {
                        ethPortsDT.Rows[index]["Cable cable length"] = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("part number"))
                    {
                        ethPortsDT.Rows[index]["Cable part number"] = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("revision"))
                    {
                        ethPortsDT.Rows[index]["Cable revision"] = Regex.Split(line, ":")[1];
                    }
                    if (line.Contains("serial number"))
                    {
                        ethPortsDT.Rows[index]["Cable serial number"] = Regex.Split(line, ":")[1];
                        return;
                    }
                }
                catch { }
        	}
        }
        //
        //----------------------------------------------------
        
        public bool getTimeoutState()
        {
            return timeouts;
        }
        //
        //----------------------------------------------------    
	}
}
